package org.compiere.process;

import java.sql.Timestamp;
import java.util.Calendar;
import java.util.TimeZone;
import java.util.logging.Level;

import org.compiere.model.Mhrmholidays;
import org.compiere.model.Mhrmsampleshedule;
import org.compiere.model.Mhrmsamplesheduleline;
import org.compiere.model.Mhrmshedulerule;
import org.compiere.model.Mhrmworkschedule;
import org.compiere.model.Mhrmworkshedulesettings;
import org.compiere.util.CLogger;
import org.compiere.util.Env;

import extend.org.compiere.utils.Util;

/**
 * The generation of working hours, according to the rules
 * @author V.Sokolov
 *
 */
public class GenerateWorkSchedule extends SvrProcess {
	
	/**	Static Logger	*/
	private static CLogger	s_log	= CLogger.getCLogger (GenerateWorkSchedule.class);
	/** */
	private int days = 0;
	Timestamp dStart;
	Timestamp dEnd;
	/** */
	private Mhrmworkshedulesettings sWorkSetting;
	/** */
	private Mhrmshedulerule sRule;
	/** */
	private Mhrmsampleshedule sSample;
	/** */
	private Mhrmsamplesheduleline[] s_lines;
	
	@Override
	protected void prepare() {
		
		//
		sWorkSetting = new Mhrmworkshedulesettings(getCtx(), getRecord_ID(), null);
		if(sWorkSetting == null){
			s_log.log(Level.SEVERE, "Not created a model Mhrmworkshedulesettings...");
			return;
		}
		
		dStart = sWorkSetting.getStartDate();
		dEnd = sWorkSetting.getEndDate();
		// number of days between two dates
		days = Util.getDays(dStart, dEnd);
		// Rule generate
		sRule = new Mhrmshedulerule(getCtx(), sWorkSetting.gethrm_shedulerule_ID(), null);
		// Pattern generation
		sSample = new Mhrmsampleshedule(getCtx(), sRule.gethrm_sampleshedule_ID(), null);
		// We define the position of the start
		s_lines = sSample.getLinesSample();
		
	}

	@Override
	protected String doIt() throws Exception {
		
		Mhrmholidays holiday = null;
		
		int position = getPosition(sRule.getDateFrom(), dStart, s_lines.length, sRule.gethrm_daynumber());
		// Set the start date of generation
		Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT")); 
		calendar.setTimeInMillis(dStart.getTime());
		calendar.add(Calendar.DAY_OF_MONTH, -1);
		
		--position;
		for(int i = 0; i <= days; i++){
			
			if((position % s_lines.length) == 0 )
				position = 0;
			
			calendar.add(Calendar.DAY_OF_MONTH, +1);
			Mhrmworkschedule sWork = new Mhrmworkschedule(getCtx(), 0, get_TrxName());
			sWork.setAD_Org_ID(Env.getAD_Org_ID(getCtx()));
			sWork.sethrm_workshedulesettings_ID(getRecord_ID());
			sWork.setIsActive(true);
			sWork.sethrm_shedulerule_ID(sWorkSetting.gethrm_shedulerule_ID());
			sWork.sethrm_datefrom(new Timestamp(calendar.getTime().getTime()));
			sWork.sethrm_onedayType_ID(s_lines[position].gethrm_dayschedule_ID());
			
			int hol = Util.getHolidayDayoff(new Timestamp(calendar.getTime().getTime()));
			if(hol != 0)
				holiday = new Mhrmholidays(getCtx(), hol, null);
			if(holiday != null){
				sWork.sethrm_holiday(holiday.ishrm_holiday());
				sWork.sethrm_dayoff(holiday.ishrm_dayoff());
				sWork.sethrm_holidays_ID(holiday.gethrm_holidays_ID());
				holiday = null;
			}
			
			sWork.saveEx();
			
			position++;
		}
		
		//
		sWorkSetting.setProcessed(true);
		sWorkSetting.saveEx();
		
		return "Generated over";
	}
	
	/**
	 * On what day to start start
	 */
	private int getPosition(Timestamp startDate, Timestamp currentDate, int length, int position){
		
		int result = 0;
		int days = Util.getDays(startDate, currentDate);
		int mod = (days % length);
		result = mod + position;
		
		if(result > length){
			result = result - length;
		}
		
		return result;
		
	}

}
